#include "game2.h"
#include "ui_game2.h"
#include "menu.h"
#include <QPainter>
#include <QDebug>
#include <QTimer>
#include <QMouseEvent>
#include <QMediaPlayer>
#include <QMediaPlaylist>

map3 map33;
QTimer *timer3=new QTimer();
int speed3=50;

map3::map3()
{
    int gx[48]={3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,7,7,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10};
    int gy[48]={3,4,5,6,7,8,3,4,5,6,7,8,1,2,9,10,1,2,9,10,1,2,5,6,9,10,1,2,5,6,9,10,1,2,5,6,7,8,9,10,1,2,5,6,7,8,9,10};
    for (int i=0;i<48;i++)
    {
        map[gx[i]][gy[i]+3]=1;
    }
    int ax[48]={1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8};
    int ay[48]={3,4,5,6,7,8,9,10,3,4,5,6,7,8,9,10,1,2,7,8,1,2,7,8,1,2,7,8,1,2,7,8,3,4,5,6,7,8,9,10,3,4,5,6,7,8,9,10};
    for (int i=0;i<48;i++)
    {
        map[ax[i]+13][ay[i]+3]=1;
    }
    int mx[52]={1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10};
    int my[52]={3,4,5,6,7,8,9,10,3,4,5,6,7,8,9,10,1,2,1,2,3,4,5,6,7,8,3,4,5,6,7,8,1,2,1,2,3,4,5,6,7,8,9,10,3,4,5,6,7,8,9,10};
    for (int i=0;i<52;i++)
    {
        map[mx[i]+24][my[i]+3]=1;
    }
    int ex[48]={1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7};
    int ey[48]={1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,5,6,9,10,1,2,5,6,9,10,1,2,5,6,9,10,1,2,5,6,9,10,1,2,9,10};
    for (int i=0;i<48;i++)
    {
        map[ex[i]+37][ey[i]+3]=1;
        map[ex[i]+37][ey[i]+31]=1;
    }
    int ox[40]={1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,7,7,8,8,8,8,8,8};
    int oy[40]={3,4,5,6,7,8,3,4,5,6,7,8,1,2,9,10,1,2,9,10,1,2,9,10,1,2,9,10,3,4,5,6,7,8,3,4,5,6,7,8};
    for (int i=0;i<40;i++)
    {
        map[ox[i]+13][oy[i]+17]=1;
    }
    int fx[40]={1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,8,8};
    int fy[40]={1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,5,6,1,2,5,6,1,2,5,6,1,2,5,6,1,2,1,2};
    for (int i=0;i<40;i++)
    {
        map[fx[i]+25][fy[i]+17]=1;
        map[fx[i]+25][fy[i]+31]=1;
    }
    int lx[32]={1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,4,4,5,5,6,6,7,7,8,8};
    int ly[32]={1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,9,10,9,10,9,10,9,10,9,10,9,10};
    for (int i=0;i<32;i++)
    {
        map[lx[i]+2][ly[i]+31]=1;
    }
    int ix[36]={1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6};
    int iy[36]={1,2,9,10,1,2,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,9,10,1,2,9,10};
    for (int i=0;i<36;i++)
    {
        map[ix[i]+14][iy[i]+31]=1;
    }
}

Game2::Game2(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Game2)
{
    ui->setupUi(this);
    connect(timer3,&QTimer::timeout,this,&Game2::timerUpdate);
    timer3->stop();
    this->setAttribute(Qt::WA_DeleteOnClose);

    if (playthrough==2||playthrough==3)
    {
        //设置音乐
        QMediaPlaylist *musicList = new QMediaPlaylist(this);
        musicList->addMedia(QUrl("qrc:/resourse/music2.mp3"));

        QMediaPlayer *soundPlayer = new QMediaPlayer(this);
        soundPlayer->setPlaylist(musicList);
        soundPlayer->play();
        musicList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
    }
}

Game2::~Game2()
{
    delete ui;
}

void Game2::paintEvent(QPaintEvent *)
{    

    QPainter painter(this);

    //设置网格颜色
    QPen pen(Qt::gray);
    painter.setPen(pen);

    //以label左上角为原点
    painter.translate(ui->label->x(),ui->label->y());

    //清空画布
    QBrush brush(Qt::white,Qt::SolidPattern);
    painter.setBrush(brush);
    painter.drawRect(0,0,ui->label->width()-1,ui->label->height()-1);

    //绘制网格
    for(int x=0;x<=map33.getwidthnum();x++)
    {
        painter.drawLine(x*map33.getwidth(),0,x*map33.getwidth(),map33.getheightnum()*map33.getheight());
    }
    for(int y=0;y<=map33.getheightnum();y++)
    {
        painter.drawLine(0,y*map33.getheight(),map33.getwidthnum()*map33.getwidth(),y*map33.getheight());
    }

    //绘制细胞
    brush.setColor(Qt::black);
    painter.setBrush(brush);
    for(int x=0;x<map33.getwidthnum();x++)
    {
        for(int y=0;y<map33.getheightnum();y++)
        {
            if(map33.getmap(x,y)==1)
                    painter.drawRect(x*map33.getwidth(),y*map33.getheight(),map33.getwidth(),map33.getheight());
        }
    }
    painter.end();

    if (playthrough!=1)
    {
        int t=map33.mapclearcheck();
        //t=1;//test
        if (t==1)
        {
            playthrough=4;
            timer3->stop();
            map33.renewmap();
            this->close();
            acquaintance *a=new acquaintance();
            a->show();
        }
    }
}

void Game2::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton)
    {
        QPoint point=event->pos()-ui->label->pos();
        //offset=event->pos()-ui->label->pos();
        if(point.x()>=0 and point.x()<=map33.getwidth()*map33.getwidthnum() and point.y()>=0 and point.y()<=map33.getheight()*map33.getheightnum())//防止超出范围
        {
            lastcellx=point.x()/map33.getwidth();
            lastcelly=point.y()/map33.getheight();
            map33.changemap(point.x()/map33.getwidth(),point.y()/map33.getheight());//改变细胞状态
            update();//重绘界面
        }
    }
}

void Game2::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons() & Qt::LeftButton)
    {
        QPoint point=event->pos()-ui->label->pos();
        //offset=event->pos()-ui->label->pos();
        if(point.x()>=0 and point.x()<=map33.getwidth()*map33.getwidthnum() and point.y()>=0 and point.y()<=map33.getheight()*map33.getheightnum())//防止超出map范围
        {
            if(lastcellx!=point.x()/map33.getwidth() or lastcelly!=point.y()/map33.getheight())
            {
                lastcellx=point.x()/map33.getwidth();
                lastcelly=point.y()/map33.getheight();
                map33.changemap(point.x()/map33.getwidth(),point.y()/map33.getheight());
                update();//重绘界面
            }
        }
    }
}

void Game2::timerUpdate()
{
    map33.mapupdate();
    update();//更新界面
}

void Game2::on_startpushButton_clicked()
{
    timer3->start(speed3);
}

void Game2::on_pausepushButton_clicked()
{
    timer3->stop();
}

void Game2::on_backpushButton_clicked()
{
    timer3->stop();
    map33.renewmap();
    this->close();
    acquaintance *a=new acquaintance();
    a->show();
}
void Game2::on_tippushButton_clicked()
{
    if (playthrough==1)
    {
        this->close();
        tip *t1=new tip();
        t1->show();
    }
}

void map3::mapupdate()
{
    int dx[8]={0,0,-1,1,-1,1,-1,1};
    int dy[8]={1,-1,0,0,1,1,-1,-1};

    memset(neighbor,0,sizeof(neighbor));//细胞清零

    //统计邻居细胞数量
    for(int x=0;x<widthnum;x++)
    {
        for(int y=0;y<heightnum;y++)
        {
            if(map[x][y]==1)
            {
                for(int i=0;i<8;i++)
                {
                    if(dx[i]+x>=0 and dx[i]+x<=widthnum and dy[i]+y>=0 and dy[i]+y<=heightnum) //防止越界
                    {
                        neighbor[dx[i]+x][dy[i]+y]++;//
                    }
                }
            }
        }
    }

    //改变细胞状态
    for(int x=0;x<widthnum;x++)
    {
        for(int y=0;y<heightnum;y++)
        {
            if(neighbor[x][y]==3)
                map[x][y]=1;
            else if(neighbor[x][y]!=2)
                map[x][y]=0;
        }
    }
}

void map3::renewmap()
{
    for(int x=0;x<widthnum;x++)
    {
        for(int y=0;y<heightnum;y++)
        {
            map[x][y]=0;
        }
    }
    int gx[48]={3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,7,7,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10};
    int gy[48]={3,4,5,6,7,8,3,4,5,6,7,8,1,2,9,10,1,2,9,10,1,2,5,6,9,10,1,2,5,6,9,10,1,2,5,6,7,8,9,10,1,2,5,6,7,8,9,10};
    for (int i=0;i<48;i++)
    {
        map[gx[i]][gy[i]+3]=1;
    }
    int ax[48]={1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8};
    int ay[48]={3,4,5,6,7,8,9,10,3,4,5,6,7,8,9,10,1,2,7,8,1,2,7,8,1,2,7,8,1,2,7,8,3,4,5,6,7,8,9,10,3,4,5,6,7,8,9,10};
    for (int i=0;i<48;i++)
    {
        map[ax[i]+13][ay[i]+3]=1;
    }
    int mx[52]={1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10};
    int my[52]={3,4,5,6,7,8,9,10,3,4,5,6,7,8,9,10,1,2,1,2,3,4,5,6,7,8,3,4,5,6,7,8,1,2,1,2,3,4,5,6,7,8,9,10,3,4,5,6,7,8,9,10};
    for (int i=0;i<52;i++)
    {
        map[mx[i]+24][my[i]+3]=1;
    }
    int ex[48]={1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7};
    int ey[48]={1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,5,6,9,10,1,2,5,6,9,10,1,2,5,6,9,10,1,2,5,6,9,10,1,2,9,10};
    for (int i=0;i<48;i++)
    {
        map[ex[i]+37][ey[i]+3]=1;
        map[ex[i]+37][ey[i]+31]=1;
    }
    int ox[40]={1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,7,7,8,8,8,8,8,8};
    int oy[40]={3,4,5,6,7,8,3,4,5,6,7,8,1,2,9,10,1,2,9,10,1,2,9,10,1,2,9,10,3,4,5,6,7,8,3,4,5,6,7,8};
    for (int i=0;i<40;i++)
    {
        map[ox[i]+13][oy[i]+17]=1;
    }
    int fx[40]={1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,8,8};
    int fy[40]={1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,5,6,1,2,5,6,1,2,5,6,1,2,5,6,1,2,1,2};
    for (int i=0;i<40;i++)
    {
        map[fx[i]+25][fy[i]+17]=1;
        map[fx[i]+25][fy[i]+31]=1;
    }
    int lx[32]={1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,4,4,5,5,6,6,7,7,8,8};
    int ly[32]={1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,9,10,9,10,9,10,9,10,9,10,9,10};
    for (int i=0;i<32;i++)
    {
        map[lx[i]+2][ly[i]+31]=1;
    }
    int ix[36]={1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,6,6};
    int iy[36]={1,2,9,10,1,2,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,9,10,1,2,9,10};
    for (int i=0;i<36;i++)
    {
        map[ix[i]+14][iy[i]+31]=1;
    }
}

int map3::mapclearcheck()
{
    bool t=1;
    for(int x=0;x<map33.widthnum;x++)
    {
        for(int y=0;y<map33.heightnum;y++)
        {
            if(map33.map[x][y]==1)
                t=0;
        }
    }
    if (t==1)
        return 1;
    else
        return 0;
}

